#include "mainWidget.h"
#include "./ui_mainWidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QCloseEvent>
#include <QMessageBox>
#include "debug.h"
#include "selfinfowidget.h"
#include "singlesessiondetailinfo.h"
#include "groupsessiondetailinfo.h"
#include "addfrienddialog.h"
#include "model/datacenter.h"
#include "toast.h"


using namespace model;

MainWidget* MainWidget::instance = nullptr;
MainWidget* MainWidget::getInstance()
{
    if(!instance) instance = new MainWidget();
    return instance;
}
MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWidget)
{
    ui->setupUi(this);
    //this->setWindowFlags(Qt::FramelessWindowHint);
    this->setWindowTitle("zzy的聊天室");
    this->setWindowIcon(QIcon(":/myResource/Image/WeChat.svg"));



    //初始化主窗口的样式布局
    initMainWindow();
    //初始化左侧窗口的样式布局
    initLeftWindow();
    //初始化中间窗口的样式布局
    initMidWindow();
    //初始化右侧窗口的样式布局
    initRightWindow();
    //初始化信号槽
    initSignalSlot();
    //初始化webSocket服务器
    initWebSocket();
}

MainWidget::~MainWidget()
{
    delete ui;
}
void MainWidget::initMainWindow()
{

    QHBoxLayout* layout = new QHBoxLayout();
    // Spacing 就是 layout 内部元素之间的间隔距离. 设为 0 就是 "紧挨着"
    layout->setSpacing(0);
    // layout 里面的元素距离四个边界的距离.
    layout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(layout);


    windowLeft = new QWidget();
    windowMid = new QWidget();
    windowRight = new QWidget();
    //注意系统的缩放
    windowLeft->setFixedWidth(70/SCALE);
    windowMid->setFixedWidth(310/SCALE);
    windowRight->setMinimumWidth(750/SCALE);


    windowLeft->setStyleSheet("QWidget { background-color: rgb(46, 46, 46); }");
    windowMid->setStyleSheet("QWidget { background-color: rgb(245, 245, 245); }");
    windowRight->setStyleSheet("QWidget { background-color: rgb(245, 245, 245); }");

    layout->addWidget(windowLeft);
    layout->addWidget(windowMid);
    layout->addWidget(windowRight);
}
void MainWidget::initLeftWindow()
{
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(20/SCALE);
    layout->setContentsMargins(0,50/SCALE,0,0);
    windowLeft->setLayout(layout);


    // 添加用户头像
    userAvatar = new QPushButton;
#if TEST_UI
    userAvatar->setIcon(QIcon(":/myResource/Image/myAvatar.jpg"));
#endif
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    connect(dataCenter,&model::DataCenter::changeAvatarDone,this,[=]()
    {
        userAvatar->setIcon(dataCenter->getMyself()->avatar);
    });
    userAvatar->setFixedSize(45/SCALE,45/SCALE);
    userAvatar->setIconSize(QSize(45/SCALE,45/SCALE));
    userAvatar->setStyleSheet("border: none;");
    layout->addWidget(userAvatar,1,Qt::AlignTop | Qt::AlignHCenter);

    // 添加会话标签页按钮
    sessionTabBtn = new QPushButton;
    sessionTabBtn->setIcon(QIcon(":/myResource/Image/ActiveSession.svg"));
    sessionTabBtn->setFixedSize(45/SCALE,45/SCALE);
    sessionTabBtn->setIconSize(QSize(30/SCALE,30/SCALE));
    sessionTabBtn->setStyleSheet("border: none;");
    layout->addWidget(sessionTabBtn,1,Qt::AlignTop | Qt::AlignHCenter);

    // 添加好友标签页按钮
    friendTabBtn = new QPushButton;

    friendTabBtn->setIcon(QIcon(":/myResource/Image/inActiveFriend.svg"));
    friendTabBtn->setFixedSize(45/SCALE,45/SCALE);
    friendTabBtn->setIconSize(QSize(30/SCALE,30/SCALE));
    friendTabBtn->setStyleSheet("border: none;");
    layout->addWidget(friendTabBtn,1,Qt::AlignTop | Qt::AlignHCenter);

    // 添加好友申请标签页按钮
    applyTabBtn = new QPushButton;
    applyTabBtn->setIcon(QIcon(":/myResource/Image/inActiveFriendApply.svg"));
    applyTabBtn->setFixedSize(45/SCALE,45/SCALE);
    applyTabBtn->setIconSize(QSize(30/SCALE,30/SCALE));
    applyTabBtn->setStyleSheet("border: none;");
    layout->addWidget(applyTabBtn,1,Qt::AlignTop | Qt::AlignHCenter);


    layout->addStretch(10);


}
void MainWidget::initMidWindow()
{

    QGridLayout* layout = new QGridLayout;
    layout->setContentsMargins(0,20/SCALE,0,0);
    layout->setHorizontalSpacing(0);
    layout->setVerticalSpacing(10);
    windowMid->setLayout(layout);



    searchEdit = new QLineEdit;
    searchEdit->setFixedSize(QSize(250/SCALE,30/SCALE));
    searchEdit->setPlaceholderText("搜索");
    searchEdit->setStyleSheet("border-radius:5px;background-color:rgb(226,226,226);padding-left:5px;");

    addFriendBtn = new QPushButton;
    addFriendBtn->setFixedSize(QSize(30/SCALE,30/SCALE));
    addFriendBtn->setIconSize(QSize(20/SCALE,20/SCALE));
    addFriendBtn->setIcon(QIcon(":/myResource/Image/addFriendPlus2.svg"));
    QString style ="QPushButton{border-radius:5px;background-color:rgb(226,226,226);}";
    style+="QPushButton:pressed{background-color:rgb(210,210,210);}";
    addFriendBtn->setStyleSheet(style);


    SFriendArea = new sessionFriendArea;


    // 为了更灵活的控制边距, 只影响搜索框按钮这一行, 不影响下方列表这一行
    // 创建空白的 widget 填充到布局管理器中.

    QWidget* spacer1 = new QWidget();
    //扩展空白widget的高度来拓宽第一行的宽度
    spacer1->setFixedHeight(38);
    spacer1->setFixedWidth(10);
    QWidget* spacer2 = new QWidget();
    spacer2->setFixedWidth(10);
    QWidget* spacer3 = new QWidget();
    spacer3->setFixedWidth(10);

    layout->addWidget(spacer1, 0, 0);
    layout->addWidget(searchEdit, 0, 1);
    layout->addWidget(spacer2, 0, 2);
    layout->addWidget(addFriendBtn, 0, 3);
    layout->addWidget(spacer3, 0, 4);
    layout->addWidget(SFriendArea, 1, 0, 1, 5);

    //加载数据,默认点击的是会话标签，不需要提前加载
    loadApplyList();
    loadFriendList();

}
void MainWidget::initRightWindow()
{
    QVBoxLayout* MVlayout = new QVBoxLayout;
    MVlayout->setSpacing(0);
    MVlayout->setContentsMargins(0,0,0,0);
    MVlayout->setAlignment(Qt::AlignTop);
    windowRight->setLayout(MVlayout);


    //1.创建上方标题栏
    QWidget* titleWidget = new QWidget;
    titleWidget->setContentsMargins(15/SCALE,0,0,0);
    titleWidget->setFixedHeight(80/SCALE);
    titleWidget->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
    titleWidget->setObjectName("titleWidget");
    titleWidget->setStyleSheet("#titleWidget{border-bottom: 1px solid rgb(214,214,214);border-left:1px solid rgb(214,214,214);}");
    MVlayout->addWidget(titleWidget);

    //添加label和button
    QHBoxLayout* hlayout = new QHBoxLayout;
    titleWidget->setLayout(hlayout);

    sessionTitleLabel = new QLabel;
    sessionTitleLabel->setFixedHeight(40/SCALE);
    sessionExtraButton = new QPushButton;
#if TEST_UI
    sessionTitleLabel->setText("测试--对方的名字&&群聊");
#endif
    sessionTitleLabel->setStyleSheet("font-size:18px;font-weight:500;");
    hlayout->addWidget(sessionTitleLabel);

    sessionExtraButton->setFixedSize(26/SCALE,26/SCALE);
    sessionExtraButton->setIcon(QIcon(":/myResource/Image/threePoint.svg"));
    sessionExtraButton->setIconSize(QSize(20/SCALE,20/SCALE));
    QString style ="QPushButton{border:none;background-color:rgb(245,245,245);}";
    style+="QPushButton:pressed{background-color:rgb(220,220,220);}";
    sessionExtraButton->setStyleSheet(style);
    hlayout->addWidget(sessionExtraButton);

    //2.添加消息展示区
    MShowArea = new messageShowArea;
    MShowArea->setObjectName("MShowArea");
    MShowArea->setStyleSheet("#MShowArea{border-radius:0px;}");
    MVlayout->addWidget(MShowArea);

    //3.添加消息编辑区
    MEditArea= new messageEditArea;
    MVlayout->addWidget(MEditArea);



}
void MainWidget::initSignalSlot()
{

    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    ///////////////////////////////////////////////////////////////
    /// 连接信号槽，处理标签页按钮切换的问题
    ///////////////////////////////////////////////////////////////
    connect(sessionTabBtn,&QPushButton::clicked,this,&MainWidget::switchToSession);
    switchToSession();
    connect(friendTabBtn,&QPushButton::clicked,this,&MainWidget::switchToFriend);
    connect(applyTabBtn,&QPushButton::clicked,this,&MainWidget::switchToApply);

    ///////////////////////////////////////////////////////////////
    /// 连接信号槽，处理点击自己头像，弹出对话框显示个人主页的问题
    ///////////////////////////////////////////////////////////////
    connect(userAvatar,&QPushButton::clicked,this,[this]()
    {
        SelfinfoWidget* selfinfoWidget = new SelfinfoWidget(this);
        selfinfoWidget->exec();
    });

    connect(sessionExtraButton,&QPushButton::clicked,this,[=]()
    {
        if(dataCenter->getCurrentSessionId().isEmpty())
        {
            Toast::showMessage("当前选中会话为空");
            return;
        }
        SessionInfo* sessionInfo = dataCenter->findSessionInfoBySId(dataCenter->getCurrentSessionId());
        if(!sessionInfo)
        {
            LOG()<<"当前会话信息为空";
            return;
        }
        bool isGroup= sessionInfo->userId=="";
        if(isGroup)
        {
            GroupSessionDetailInfo* groupSessionDetailInfo = new GroupSessionDetailInfo(this,*sessionInfo);
            groupSessionDetailInfo->exec();
        }
        else
        {
            UserInfo* userInfo = dataCenter->findFriendByUId(sessionInfo->userId);
            if(!userInfo)
            {
                LOG()<<"当前会话用户信息未找到";
                return;
            }
            SingleSessionDetailInfo* singleSessionDetailInfo = new SingleSessionDetailInfo(this,*userInfo);
            singleSessionDetailInfo->exec();
        }
    });
    connect(addFriendBtn,&QPushButton::clicked,this,[=]()
    {
        AddFriendDialog* addFriendDialog = new AddFriendDialog(this);
        addFriendDialog->exec();
    });
    connect(searchEdit,&QLineEdit::textEdited,this,[=]()
    {
        AddFriendDialog* addFriendDialog = new AddFriendDialog(this);
        addFriendDialog->setSearchKey(searchEdit->text());
        searchEdit->setText("");
        addFriendDialog->exec();
    });

    //获取完成个人信息后，设置个人头像
    connect(dataCenter,&model::DataCenter::getMyselfDone,this,[=]()
    {
        userAvatar->setIcon(dataCenter->getMyself()->avatar);
    });
    //通过网络获得启动主页的头像,获得到的结果储存到myself
    dataCenter->getMyselfAsync();

    connect(dataCenter,&model::DataCenter::deleteFriend,this,[=](const QString& uid)
    {
        auto result = QMessageBox::warning(this,"确认删除","确认删除当前好友?",QMessageBox::Ok|QMessageBox::Cancel);
        if(result!=QMessageBox::Ok)
        {
            LOG()<<"用户取消删除好友";
            return;
        }
        model::DataCenter* dataCenter = model::DataCenter::getInstance();
        dataCenter->deleteFriendAsync(uid);
    });
    connect(dataCenter,&model::DataCenter::deleteFriendDone,this,[=]()
    {
        updateFriendList();
        updateSessionList();
        LOG()<<"删除好友完全处理完毕";
    });
    connect(dataCenter,&model::DataCenter::clearCurrentSession,this,[=]()
    {
        sessionTitleLabel->setText("");
        MShowArea->clear();
    });
    //服务器发送好友申请后，更新界面
    connect(dataCenter,&model::DataCenter::acceptFriendApplyDone,this,[=]()
    {
        if(activeTab==ActiveTab::APPLY)
            this->updateApplyList();
    });
    connect(dataCenter,&model::DataCenter::processFriendApplyDone,this,[=]()
    {
        if(activeTab==ActiveTab::APPLY)
            this->updateApplyList();
        else if(activeTab==ActiveTab::FRIEND)
            this->updateFriendList();
    });
    connect(dataCenter,&model::DataCenter::createSessionDone,this,[=]()
    {
        if(activeTab==ActiveTab::SESSION)
            this->updateSessionList();
    });
    connect(dataCenter,&model::DataCenter::getVerifyCodeDone,this,[]()
    {
        Toast::showMessage("发送验证码成功");
    });



}
void MainWidget::switchToSession()
{
    //1.切换标签页
    activeTab = ActiveTab::SESSION;
    //2.更新图片
    sessionTabBtn->setIcon(QIcon(":/myResource/Image/ActiveSession.svg"));
    friendTabBtn->setIcon(QIcon(":/myResource/Image/inActiveFriend.svg"));
    applyTabBtn->setIcon(QIcon(":/myResource/Image/inActiveFriendApply.svg"));
    loadSessionList();
}
void MainWidget::switchToFriend()
{
    //1.切换标签页
    activeTab = ActiveTab::FRIEND;
    //2.更新图片
    sessionTabBtn->setIcon(QIcon(":/myResource/Image/inActiveSession.svg"));
    friendTabBtn->setIcon(QIcon(":/myResource/Image/ActiveFriend.svg"));
    applyTabBtn->setIcon(QIcon(":/myResource/Image/inActiveFriendApply.svg"));
    loadFriendList();
}
void MainWidget::switchToApply()
{
    //1.切换标签页
    activeTab = ActiveTab::APPLY;
    //2.更新图片
    sessionTabBtn->setIcon(QIcon(":/myResource/Image/inActiveSession.svg"));
    friendTabBtn->setIcon(QIcon(":/myResource/Image/inActiveFriend.svg"));
    applyTabBtn->setIcon(QIcon(":/myResource/Image/ActiveFriendApply.svg"));
    loadApplyList();
}

void MainWidget::switchSession(const QString &userId)
{
    switchToSession();
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    QList<SessionInfo>* sessionList = dataCenter->getSessionList();
    if(sessionList==nullptr)
    {
        LOG()<<"尚未加载会话列表";
        return;
    }
    for(int i =0;i<sessionList->size();i++)
    {
        if((*sessionList)[i].userId==userId)
        {
            SFriendArea->clickItem(i);
            return;
        }
    }
}

void MainWidget::loadSessionList()
{
    //本地数据存在就直接加载本地数据，不存在则在网络获取
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getSessionList())
        updateSessionList();
    else
    {
        //从网络获取数据
        connect(dataCenter,&model::DataCenter::getSessionListDone,this,&MainWidget::updateSessionList,Qt::UniqueConnection);
        dataCenter->getSessionListAsync();
    }
}

void MainWidget::loadFriendList()
{
    //本地数据存在就直接加载本地数据，不存在则在网络获取
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getFriendList())
        updateFriendList();
    else
    {
        //从网络获取数据
        connect(dataCenter,&model::DataCenter::getFriendListDone,this,&MainWidget::updateFriendList,Qt::UniqueConnection);
        dataCenter->getFriendListAsync();
    }
}

void MainWidget::loadApplyList()
{
    //本地数据存在就直接加载本地数据，不存在则在网络获取
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getApplyList())
        updateApplyList();
    else
    {
        //从网络获取数据
        connect(dataCenter,&model::DataCenter::getApplyListDone,this,&MainWidget::updateApplyList,Qt::UniqueConnection);
        dataCenter->getApplyListAsync();
    }

}

void MainWidget::loadRecentMessage(const QString& sessionId)
{
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getRecentMessageList(sessionId))
        updateRencentMessage(sessionId);
    else
    {
        connect(dataCenter,&DataCenter::getRecentMessageDone,this,&MainWidget::updateRencentMessage,Qt::UniqueConnection);
        dataCenter->getRecentMessageListAsync(sessionId,true);
    }

}

void MainWidget::updateSessionList()
{
    if(activeTab!=ActiveTab::SESSION)
        return;
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    QList<model::SessionInfo>* sessionList = dataCenter->getSessionList();

    SFriendArea->clear();

    for(auto& s:*sessionList)
    {
        ItemType t = ItemType::SESSION;
        QString sid = s.chatSessionId;
        QIcon avatar = s.avatar;
        QString sName = s.chatSessionName;
        QString lastMessage;
        switch(s.lastMessage.messageType)
        {
            case model::MessageType::TEXT_TYPE:
            {
                lastMessage = s.lastMessage.content;
                break;
            }
            case model::MessageType::FILE_TYPE:
            {
                lastMessage = "[文件]";
                break;
            }
            case model::MessageType::IMAGE_TYPE:
            {
                lastMessage = "[图片]";
                break;
            }
            case model::MessageType::SPEECH_TYPE:
            {
                lastMessage = "[语音]";
                break;
            }
            default:
            {
                LOG()<<"错误的消息类型,lastMessageType = "<<(size_t)s.lastMessage.messageType;
            }
        }
        SFriendArea->addItem(t,sid,avatar,sName,lastMessage);
    }


}

void MainWidget::updateFriendList()
{
    if(activeTab!=ActiveTab::FRIEND)
        return;
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    auto friendList = dataCenter->getFriendList();
    SFriendArea->clear();
    for(auto &f:*friendList)
        SFriendArea->addItem(ItemType::FRIEND,f.userId,f.avatar,f.nickname,"");
}

void MainWidget::updateApplyList()
{
    if(activeTab!=ActiveTab::APPLY)
        return;
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    auto applyList = dataCenter->getApplyList();
    SFriendArea->clear();
    for(auto& a:*applyList)
        SFriendArea->addItem(ItemType::APPLY,a.userId,a.avatar,a.nickname,"");
}

void MainWidget::updateRencentMessage(const QString &sessionId)
{
    //1.拿到内存数据
    DataCenter* dataCenter = DataCenter::getInstance();
    QList<Message>* msgList =  dataCenter->getRecentMessageList(sessionId);
    if(!msgList)
        return;
    MShowArea->clear();
    //2.增添最近消息到界面
    for(auto &m:*msgList)
    {
        bool isLeft = dataCenter->getMyself()->userId!=m.sender.userId;
        LOG()<<"left:"<<isLeft;
        MShowArea->addMessage(isLeft,m);
    }
    //3.设置会话标题
    auto sessionInfo = dataCenter->findSessionInfoBySId(sessionId);
    if(sessionInfo)
        sessionTitleLabel->setText(sessionInfo->chatSessionName);
    //4.保存当前选中会话
    dataCenter->setCurrentSessionId(sessionId);
    //5.把滚动条拉到末尾
    MShowArea->scrollToEnd();
}

void MainWidget::initWebSocket()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->initWebSocket();
}









